﻿using System;
using System.Collections.Generic;
using System.CodeDom;
using BMC.ARSystem;

namespace Wicresoft.EKA.NRemedy.CodeGenerate
{
    public class GenerateDiaryProperty : GeneratePropertyBase
    {
        public override void Create(CodeTypeDeclaration classType, string propertyName, string propertyType, Limit limit, Dictionary<string, object> attributePropertyValues, GeneratePropertyDelegate propertyDelegate, IGeneratePropertyAttribute attributeGenerator)
        {
            if (classType == null) throw new ArgumentNullException("classType");
            if (string.IsNullOrEmpty(propertyName)) throw new ArgumentNullException("propertyName");
            if (string.IsNullOrEmpty(propertyType)) throw new ArgumentNullException("propertyType");
            //if (limit == null) throw new ArgumentNullException("selectionLimit");
            if (attributePropertyValues == null) throw new ArgumentNullException("attributePropertyValues");
            if (propertyDelegate == null) throw new ArgumentNullException("propertyDelegate");
            if (attributeGenerator == null) throw new ArgumentNullException("attributeGenerator");

            base.Create(classType, propertyName, propertyType, limit, attributePropertyValues, propertyDelegate, attributeGenerator);

            if (propertyDelegate(propertyName))
            {
                GenerateNameResolver gnr = new GenerateNameResolver();
                //set
                string diarySetName = gnr.DiaryPropertyNameSetResolver(propertyName);
                CodeMemberProperty _propertyset = new CodeMemberProperty();
                _propertyset.Name = diarySetName;
                _propertyset.Type = new CodeTypeReference("String");
                _propertyset.Attributes = MemberAttributes.Public | MemberAttributes.Final;
                string fieldNameset = gnr.DiaryFieldNameSetResolver(propertyName);
                _propertyset.GetStatements.Add(new CodeMethodReturnStatement(new CodeFieldReferenceExpression(new CodeThisReferenceExpression(), fieldNameset)));
                _propertyset.SetStatements.Add(new CodeAssignStatement(new CodeFieldReferenceExpression(new CodeThisReferenceExpression(), fieldNameset), new CodePropertySetValueReferenceExpression()));
                _propertyset.SetStatements.Add(new CodeMethodInvokeExpression(new CodeMethodReferenceExpression(new CodeThisReferenceExpression(), "OnPropertyChanged"), new CodeExpression[] { new CodePrimitiveExpression(diarySetName) }));

                //get
                string diaryGetName = gnr.DiaryPropertyNameGetResolver(propertyName);
                CodeMemberProperty _propertyget = new CodeMemberProperty();
                _propertyget.Name = diaryGetName;
                _propertyget.Type = new CodeTypeReference("DiaryList");
                _propertyget.Attributes = MemberAttributes.Public | MemberAttributes.Final;
                string fieldNameget = gnr.DiaryFieldNameGetResolver(propertyName);
                _propertyget.GetStatements.Add(new CodeMethodReturnStatement(new CodeFieldReferenceExpression(new CodeThisReferenceExpression(), fieldNameget)));
                //ToDo:WangDi
                _propertyget.SetStatements.Add(new CodeAssignStatement(new CodeFieldReferenceExpression(new CodeThisReferenceExpression(), fieldNameget), new CodePropertySetValueReferenceExpression()));
                _propertyget.SetStatements.Add(new CodeMethodInvokeExpression(new CodeMethodReferenceExpression(new CodeThisReferenceExpression(), "OnPropertyChanged"), new CodeExpression[] { new CodePrimitiveExpression(diaryGetName) }));

                //add attribute

                if(attributePropertyValues.ContainsKey("BinderAccess"))
                    attributePropertyValues["BinderAccess"] = ModelBinderAccessLevel.OnlyUnBind;
                else
                    attributePropertyValues.Add("BinderAccess", ModelBinderAccessLevel.OnlyUnBind);
                attributeGenerator.Create(_propertyset, typeof(ARFieldAttribute), attributePropertyValues);

                if (attributePropertyValues.ContainsKey("BinderAccess"))
                    attributePropertyValues["BinderAccess"] = ModelBinderAccessLevel.OnlyBind;
                else
                    attributePropertyValues.Add("BinderAccess", ModelBinderAccessLevel.OnlyBind);
                attributeGenerator.Create(_propertyget, typeof(ARFieldAttribute), attributePropertyValues);

                classType.Members.Add(_propertyget);
                classType.Members.Add(_propertyset);
            }
        }
    }
}
